package com.zhiwang.planet.ui.main

import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.text.TextUtils
import android.view.*
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import com.cmcm.cmgame.CmGameSdk
import com.cmcm.cmgame.IGameAccountCallback
import com.cmcm.cmgame.IGamePlayTimeCallback
import com.zhiwang.planet.BuildConfig
import com.zhiwang.planet.R
import com.zhiwang.planet.databinding.FragmentEntertain2Binding
import com.zhiwang.planet.di.component.DaggerUserComponent
import com.zhiwang.planet.di.module.AccountModule
import com.zhiwang.planet.di.module.AutoDisposeModule
import com.zhiwang.planet.exception.ExpiredException
import com.zhiwang.planet.mvp.p.UserPresenter
import com.zhiwang.planet.mvvm.viewmodel.ItemDecorationViewModel
import com.zhiwang.planet.mvvm.viewmodel.ShareViewModel
import com.zhiwang.planet.mvvm.viewmodel.entertain.EntertainViewModel
import com.zhiwang.planet.mvvm.viewmodel.main.sharedViewModels
import com.zhiwang.planet.ui.BaseFragment
import com.zhiwang.planet.ui.my.BindPhoneActivity
import com.zhiwang.planet.ui.my.MyGameListActivity
import com.zhiwang.planet.util.Toaster
import com.zhiwang.planet.util.TokenManager
import com.zhiwang.planet.util.quickStartActivity
import com.zhiwang.planet.widget.AMPLITUDE
import com.zhiwang.planet.widget.SimpleDialogBuilder
import kotlinx.android.synthetic.main.fragment_entertain2.*
import kotlinx.android.synthetic.main.play_time_dialog.view.*
import org.greenrobot.eventbus.EventBus
import javax.inject.Inject
import kotlin.math.abs


interface PlayGameProxy {

    fun play(id: String)

    fun more()
}

class EntertainFragment : BaseFragment(), IGamePlayTimeCallback, IGameAccountCallback, PlayGameProxy {

    override fun play(id: String) {
        playGame(id)
    }

    override fun more() {
        quickStartActivity(MyGameListActivity::class.java)
    }


    private val TAG = "EntertainFragment"

    @Inject
    lateinit var userPresenter: UserPresenter

    var gameId: String = ""

    var playing = false

    var gameStartTime: Long = 0L

    var currToken: String = ""

    @Inject
    lateinit var entertainViewModel: EntertainViewModel

    @Inject
    lateinit var decorVM : ItemDecorationViewModel

    val shareViewModel by sharedViewModels<ShareViewModel>()


    private val handler = H()

    private inner class H : Handler() {

        private val INTERVAL: Long = 70// 1000 ÷ 16 = 62

        override fun handleMessage(msg: Message?) {
            if ((msg?.what ?: 0) == 0) {
                update()
                sendEmptyMessageDelayed(0, INTERVAL)
            }
        }

        private fun update() {
//            video_item?.apply { updateItem(this) }
//            fiction_item?.apply { updateItem(this) }
            updatePlanet()
        }


        private fun updateItem(childView: View) {
            val speed = childView.getTag(R.string.KEY_SPEED) as Float
            val isUp = childView.getTag(R.string.KEY_DIRECTION) as Int == 0
            if (isUp) {
                childView.y -= speed
            } else childView.y += speed
            val amplitude = childView.y - childView.top
            if (abs(amplitude) > AMPLITUDE)
                reverseDirection(childView, isUp)
        }

        private fun reverseDirection(childView: View, up: Boolean) {
            if (up) childView.setTag(R.string.KEY_DIRECTION, 1)
            else childView.setTag(R.string.KEY_DIRECTION, 0)
        }
    }

    private fun updatePlanet() {
//        entertain_planet?.rotation = entertain_planet?.rotation?.plus(1f) ?: 0f
    }

    private fun floatItems() {

//        fiction_item.setTag(R.string.KEY_SPEED, Random.nextFloat() + 0.5f)
//        fiction_item.setTag(R.string.KEY_DIRECTION, 1)
//
//        video_item.setTag(R.string.KEY_SPEED, Random.nextFloat() + 0.5f)
//        video_item.setTag(R.string.KEY_DIRECTION, 0)

//        loopFloat()

    }

    private fun loopFloat() {
        handler.sendEmptyMessage(0)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        DaggerUserComponent.builder()
                .appComponent(getAppComponent())
                .accountModule(AccountModule(context as AppCompatActivity))
                .autoDisposeModule(AutoDisposeModule(this))
                .build()
                .inject(this)
//        setHasOptionsMenu(true)
    }


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {

        val view = inflater.inflate(R.layout.fragment_entertain2, container, false)
        val binding = DataBindingUtil.bind<FragmentEntertain2Binding>(view)

        binding?.vm = entertainViewModel
        binding?.decorVm = decorVM
        entertainViewModel.playCallBack = this
        binding?.shareViewModel = shareViewModel
        binding?.lifecycleOwner = viewLifecycleOwner
        return view

    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.entertain_rule, menu)
        super.onCreateOptionsMenu(menu, inflater)

    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        entertainViewModel.gamePlayedTime.observe(viewLifecycleOwner, Observer { time ->
            if (entertainViewModel.gameExcuted.value != true) {
                userPresenter.postTinyGamePlayTimeAndGetToken(
                        entertainViewModel.gamePlayedId.value!!,
                        time,
                        currToken,
                        ::onPlayTimeHandleIn,
                        ::onNewToken,
                        ::onError)
            }
        })
    }


    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == R.id.entertain_help) {
            showRuleDialog()
        }
        return super.onOptionsItemSelected(item)

    }

    private fun showRuleDialog() {

        SimpleDialogBuilder()
                .title("娱乐规则")
                .notCenter()
                .scaleAnim()
                .content(entertainViewModel.ruleMsg)
                .buttonText("我知道了")
                .build(requireActivity())
                .show()
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        (activity as AppCompatActivity).setSupportActionBar(entertain_toolbar)
        floatItems()
        entertainViewModel.start()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {

                override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {

                }

            })
        }
    }


    override fun onStart() {
        super.onStart()
        CmGameSdk.setGameAccountCallback(this)
        CmGameSdk.setGameAccountCallback(this)
        if (playing) {
            val timeSec = ((System.currentTimeMillis() - gameStartTime) / 1000).toInt()
            triggerGamePlayTask(gameId, timeSec)
        }
        entertainViewModel.loadTodayProfit()

    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        CmGameSdk.setGamePlayTimeCallback(this)
        CmGameSdk.setGameAccountCallback(this)
    }

    override fun onDetach() {
        super.onDetach()
        CmGameSdk.removeGamePlayTimeCallback()
        CmGameSdk.removeGameAccountCallback()
    }

    override fun onGameAccount(accountToken: String) {

        requireActivity().runOnUiThread {

            TokenManager.saveMiniGameAccount(accountToken)

            userPresenter.postTinyGameLoggedAccountInfo(accountToken, ::onError)
        }
    }

    override fun gamePlayTimeCallback(gameId: String, gamePlayedTimeSeconds: Int) {
        triggerGamePlayTask(gameId, gamePlayedTimeSeconds)
//        userPresenter.postTinyGamePlayTimeAndGetToken(gameId, gamePlayedTimeSeconds, currToken, ::onPlayTimeHandleIn, ::onNewToken, ::onError)
    }

    fun triggerGamePlayTask(gameId: String, playedTime: Int) {
        playing = false
        entertainViewModel.gameExcuted.value = false
        entertainViewModel.gamePlayedId.value = gameId
        entertainViewModel.gamePlayedTime.value = playedTime
    }


    fun onNewToken(token: String) {
        currToken = token
    }



    fun onPlayTimeHandleIn(msg: String?, beanReward: String?) {
        entertainViewModel.gameExcuted.value = true
        currToken = ""
        val view = layoutInflater.inflate(R.layout.play_time_dialog, null)


        val create = AlertDialog.Builder(requireActivity())
                .setView(view)
                .create()

        view.tv_reward_diamond.visibility = if (TextUtils.isEmpty(msg)) View.GONE else View.VISIBLE
        view.tv_reward_diamond.text = "+$msg"

        view.tv_reward_bean.visibility = if (TextUtils.isEmpty(beanReward)) View.GONE else View.VISIBLE
        view.tv_reward_bean.text = "+$beanReward"

        view.dialog_button.setOnClickListener {
            context?.apply {
                create.dismiss()
            }
        }
        create.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        create.show()

        entertainViewModel.loadTodayProfit()
    }

    override fun onError(t: Throwable) {
        clearGameToken()
        if (t !is ExpiredException || t.message?.contains("时间还不满") != true)
            SimpleDialogBuilder()
                    .title("温馨提示")
                    .titleTextColor(R.color.colorPrimary)
                    .buttonText("我知道了")
                    .content(t.message ?: "")
                    .build(requireActivity())
                    .show()

        else onAuthExpired()
    }


    //一般這個時候並不知曉後臺什麽錯誤，直接置空token,避免後續 繼續使用無效token
    private fun clearGameToken() {

        currToken = ""
    }


    fun playGame(gameId: String) {

        if (isTokenValid()) {

            if (CmGameSdk.hasGame(gameId)) {
                this.gameId = gameId
                val tinyGameAccount = TokenManager.miniGameAccount()
                if (TokenManager.hasMiniGameAccount().not()) //还没有提交过后台服务器游戏账户信息，请求后台服务器游戏账户信息
                    userPresenter.restoreOrCreateAccountAndPlayGame(
                            restoreAndPlay = ::restoreAccountAndPlayGame,
                            createAndPlay = ::createAccountAndPlayGame,
                            onError = ::onError)
                else {
                    //直接使用本地缓存的游戏账户
                    restoreAccountAndPlayGame(tinyGameAccount)
                    userPresenter.postTinyGameLoggedAccountInfo(tinyGameAccount, ::onError)
                }

            }
        } else userPresenter.getTinyGameToken(::onNewToken, ::onError) {
            if (CmGameSdk.hasGame(gameId)) {
                this.gameId = gameId
                val tinyGameAccount = TokenManager.miniGameAccount()
                if (TokenManager.hasMiniGameAccount().not()) //还没有提交过后台服务器游戏账户信息，请求后台服务器游戏账户信息
                    userPresenter.restoreOrCreateAccountAndPlayGame(
                            restoreAndPlay = ::restoreAccountAndPlayGame,
                            createAndPlay = ::createAccountAndPlayGame,
                            onError = ::onError)
                else {
                    //直接使用本地缓存的游戏账户
                    restoreAccountAndPlayGame(tinyGameAccount)
                    userPresenter.postTinyGameLoggedAccountInfo(tinyGameAccount, ::onError)
                }

            }
        }
    }

    fun isTokenValid(): Boolean {
        return TextUtils.isEmpty(currToken).not()
    }

    /**
     * 使用之前缓存的游戏账号继续 玩游戏
     */
    fun restoreAccountAndPlayGame(accountToken: String) {
        if (playing) return
        CmGameSdk.restoreCmGameAccount(accountToken)
        playing = true
        gameStartTime = System.currentTimeMillis()
        CmGameSdk.startH5Game(gameId)
    }

    /**
     * 创建游戏账户后 玩游戏
     */
    fun createAccountAndPlayGame() {
        if (playing) return
//        CmGameSdk.initCmGameAccount()
        CmGameSdk.restoreCmGameAccount(null)
        CmGameSdk.clearCmGameAccount()
        playing = true
        gameStartTime = System.currentTimeMillis()
        CmGameSdk.startH5Game(gameId)
    }

    private fun showBindPhoneAlertDialog() {

        SimpleDialogBuilder()
                .title("提示")
                .titleTextColor(R.color.colorPrimary)
                .buttonText("我知道了")
                .content("请先绑定手机号")
                .onButtonClick(View.OnClickListener {
                    quickStartActivity(BindPhoneActivity::class.java)
                })
                .build(requireContext())
                .show()
    }

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        if (hidden.not()) {
            entertainViewModel.start()
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        if (BuildConfig.DEBUG)
            Toaster.message("娱乐页面已销毁")
        EventBus.getDefault().unregister(this)
    }
}
